//--------------------------------------------------------------------------------------------
//    : 
//      Component name  : fpadd_stage4
//      Author          : 
//      Company         : 
//
//      Description     : 
//
//
//--------------------------------------------------------------------------------------------


module FPadd_stage4(A_SIGN_stage3, B_XSIGN_stage3, EXP_base, add_out, clk, isINF_tab_stage3, isNaN_stage3, isZ_tab_stage3, EXP_norm, OV_stage4, SIG_norm, Z_SIGN_stage4, isINF_tab_stage4, isNaN_stage4, isZ_tab_stage4, zero_stage4);
   input         A_SIGN_stage3;
   input         B_XSIGN_stage3;
   input [7:0]   EXP_base;
   input [28:0]  add_out;
   input         clk;
   input         isINF_tab_stage3;
   input         isNaN_stage3;
   input         isZ_tab_stage3;
   output [7:0]  EXP_norm;
   reg [7:0]     EXP_norm;
   output        OV_stage4;
   reg           OV_stage4;
   output [27:0] SIG_norm;
   reg [27:0]    SIG_norm;
   output        Z_SIGN_stage4;
   reg           Z_SIGN_stage4;
   output        isINF_tab_stage4;
   reg           isINF_tab_stage4;
   output        isNaN_stage4;
   reg           isNaN_stage4;
   output        isZ_tab_stage4;
   reg           isZ_tab_stage4;
   output        zero_stage4;
   reg           zero_stage4;
   
   
   wire [7:0]    EXP_norm_int;
   wire [7:0]    EXP_selC;
   reg           OV;
   wire [27:0]   SIG_norm_int;
   wire [27:0]   SIG_selC;
   reg           Z_SIGN;
   wire          add_out_sign;
   wire          zero;
   
   
   always @(posedge clk)
      
      begin
         Z_SIGN_stage4 <= Z_SIGN;
         OV_stage4 <= OV;
         EXP_norm <= EXP_norm_int;
         SIG_norm <= SIG_norm_int;
         zero_stage4 <= zero;
         isINF_tab_stage4 <= isINF_tab_stage3;
         isNaN_stage4 <= isNaN_stage3;
         isZ_tab_stage4 <= isZ_tab_stage3;
      end
   
   assign add_out_sign = add_out[28];
   
   
   always @(A_SIGN_stage3 or B_XSIGN_stage3 or add_out_sign)
   begin: SignLogic_truth_process
      reg [2:0]     b1_A_SIGN_stage3B_XSIGN_stage3add_out_sign;
      b1_A_SIGN_stage3B_XSIGN_stage3add_out_sign = {A_SIGN_stage3, B_XSIGN_stage3, add_out_sign};
      
      case (b1_A_SIGN_stage3B_XSIGN_stage3add_out_sign)
         3'b000 :
            begin
               OV <= 1'b0;
               Z_SIGN <= 1'b0;
            end
         3'b001 :
            begin
               OV <= 1'b1;
               Z_SIGN <= 1'b0;
            end
         3'b010 :
            begin
               OV <= 1'b0;
               Z_SIGN <= 1'b0;
            end
         3'b011 :
            begin
               OV <= 1'b0;
               Z_SIGN <= 1'b1;
            end
         3'b100 :
            begin
               OV <= 1'b0;
               Z_SIGN <= 1'b0;
            end
         3'b101 :
            begin
               OV <= 1'b0;
               Z_SIGN <= 1'b1;
            end
         3'b110 :
            begin
               OV <= 1'b0;
               Z_SIGN <= 1'b1;
            end
         3'b111 :
            begin
               OV <= 1'b1;
               Z_SIGN <= 1'b1;
            end
         default :
            begin
               OV <= 1'b0;
               Z_SIGN <= 1'b0;
            end
      endcase
   end
   
   
   FPadd_normalize I8(.EXP_in(EXP_selC), .SIG_in(SIG_selC), .EXP_out(EXP_norm_int), .SIG_out(SIG_norm_int), .zero(zero));
   
   FPselComplement #(.SIG_width(28)) I12(.SIG_in(add_out), .EXP_in(EXP_base), .SIG_out(SIG_selC), .EXP_out(EXP_selC));
   
endmodule
